<?php

namespace Library;

use Library\Wx;
use Think\Log;

/**
 * 微信oAuth认证示例
 */
class Wxauth {
    public $open_id;
    public $wxuser;

    /*
    * OAuth 获取用户信息第一步
    * 第一步：用户同意授权，获取code
    *      在确保微信公众账号拥有授权作用域（scope参数）的权限的前提下
    *     （服务号获得高级接口后，默认带有scope参数中的snsapi_base和snsapi_userinfo），
    *      引导关注者打开如下页面：
    *      用户同意授权后 
    *      如果用户同意授权，页面将跳转至 redirect_uri/?code=CODE&state=STATE。
    *      若用户禁止授权，则重定向后不会带上code参数，仅会带上state参数redirect_uri?state=STATE
    * 第二步：通过code换取网页授权access_token
    *      首先请注意，这里通过code换取的网页授权access_token,与基础支持中的access_token不同。
    *      公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base，
    *      则本步骤中获取到网页授权access_token的同时，也获取到了openid，snsapi_base式的网页授权流程即到此为止。
    *      
    * 第三步：刷新access_token（如果需要）
    * 第四步：拉取用户信息(需scope为 snsapi_userinfo)
    * 附：检验授权凭证（access_token）是否有效 
    */
    public function wxoauth() {
        $scope = 'snsapi_base';
        $code = isset($_GET['code']) ? $_GET['code'] : '';
        $token_time = isset($_SESSION['token_time']) ? $_SESSION['token_time'] : 0;
        if (APP_ENV == 'ONLINE' && isset($_SESSION['open_id']) && isset($_SESSION['wxuser']) && isset($_SESSION['user_id']) &&
            isset($_SESSION['user_token']) && $token_time > time() - 3600) {
            $this->open_id = $_SESSION['open_id'];
            return $this->open_id;
        } else if (APP_ENV == 'DEV' &&  !isset($_GET['redirect_uri']) &&  isset($_SESSION['open_id']) && isset($_SESSION['wxuser']) && isset($_SESSION['user_id']) &&
            isset($_SESSION['user_token']) && $token_time > time() - 3600) {
            $this->open_id = $_SESSION['open_id'];
            return $this->open_id;
        } else {
            //正常流程,第三步到这里
            if ($code) {
                /*
                 * 下面的判断,支持获取code后跳转到外部域名地址, 目前只在测试环境使用,redirect_uri为完整的url带XXXX.html
                 */
                if (APP_ENV == 'DEV') {
                    if (isset($_GET['redirect_uri']) && $_GET['redirect_uri'] != '') {
                        $urlPara['ticket'] = $_GET['ticket'];
                        $urlPara['activityid'] = $_GET['activityid'];
                        $urlPara['code'] = $_GET['code'];
                        $urlPara['state'] = $_GET['state'];
                        $externalUrl =  $_GET['redirect_uri'].'?'.http_build_query($urlPara);
                        redirect($externalUrl);
                    }
                }
                $json = Wx::getOauthAccessToken();
                if (!$json) {
                    Log::record(Wx::getLastErrCode());
                    if (Wx::getLastErrCode() == 40029) {
                        /*
                         * 40029为invalid code, 就是code码过期
                         * session 过期后, 有一定概率进入到该分之, 若session 时长设置的较短,则这部分代码,必须打开
                         *  若session时长较长,则这个分之意义不大。
                         */
                        unset($_GET['code']);
                        $url = 'http://' . $_SERVER['HTTP_HOST'].'?'.http_build_query($_GET);
                        $_SESSION['wx_redirect'] = $url;

                        Log::record($url);
                        if ($url) {
                            $oauth_url = Wx::getOauthRedirect($url, "wxbase", $scope);
                            header('Location: ' . $oauth_url);
                            exit;
                        }
                    }
                    unset($_SESSION['wx_redirect']);
                    Log::record('getOauthAccessToken return falses');
                    return false;
                }

                $user = User::getInstance();
                $_SESSION['open_id'] = $this->open_id = $json["openid"];
                $access_token = $json['access_token'];
                $_SESSION['user_token'] = $access_token;
                $_SESSION['token_time'] = time();

                $userinfo = Wx::getUserInfo($this->open_id);

                // \Think\Log::record('new user'.$userinfo);
                if ($userinfo && !empty($userinfo['nickname'])) {
                    Log::record('getUserInfo');
                    $this->wxuser = array(
                        'open_id' => $this->open_id,
                        'nickname' => $userinfo['nickname'],
                        'sex' => intval($userinfo['sex']),
                        'location' => $userinfo['province'] . '-' . $userinfo['city'],
                        'avatar' => $userinfo['headimgurl']
                    );
                    $userid = $user->saveWxUserInfo($this->wxuser);
                } elseif (strstr($json['scope'], 'snsapi_userinfo') !== false) {
                    Log::record('getOauthUserinfo');
                    $userinfo = Wx::getOauthUserinfo($access_token, $this->open_id);
                    if ($userinfo && !empty($userinfo['nickname'])) {
                        $this->wxuser = array(
                            'open_id' => $this->open_id,
                            'nickname' => $userinfo['nickname'],
                            'sex' => intval($userinfo['sex']),
                            'location' => $userinfo['province'] . '-' . $userinfo['city'],
                            'avatar' => $userinfo['headimgurl']
                        );
                        $userid = $user->saveWxUserInfo($this->wxuser);
                    } else {
                        return $this->open_id;
                    }
                } else {
                    //正常情况下 下一步到$scope = 'snsapi_userinfo';
                    Log::record('getUserInfo error goto getOauthUserinfo');
                }
                if ($userinfo && !empty($userinfo['nickname']) && $this->wxuser) {
                    $_SESSION['wxuser'] = $this->wxuser;
                    $_SESSION['open_id'] = $json["openid"];
                    $_SESSION['user_id'] = $userid;

                    unset($_SESSION['wx_redirect']);
                    return $this->open_id;
                }
                $scope = 'snsapi_userinfo';
            } 
            if ($scope == 'snsapi_base') { //正常流程,第一步到这里
                $url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
                $_SESSION['wx_redirect'] = $url;
            } else {
                $url = $_SESSION['wx_redirect'];
            }
            if (!$url) {
                unset($_SESSION['wx_redirect']);
                Log::record('url is NULL');
                return false;
            }

            //正常流程,第二步到这里
            $oauth_url = Wx::getOauthRedirect($url, "wxbase", $scope);
            header('Location: ' . $oauth_url);
            exit;
        }
    }

    
}
